/**
 *  Copyright (C) 2008-2013  Telosys project org. ( http://www.telosys.org/ )
 *
 *  Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *          http://www.gnu.org/licenses/lgpl.html
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.telosys.persistence.sql;

import org.telosys.util.StrUtil;

/**
 * Splitter tool (to split a SQL SELECT request in 4 parts)
 *  
 * @author Laurent Guerin
 *
 */
public class SqlQuerySplitter 
{
	private final static String ORDER = "ORDER" ;
	private final static String GROUP = "GROUP" ;
	private final static String WHERE = "WHERE" ;
	private final static String FROM  = "FROM" ;
	
	private String _sSqlOrderByGroupBy = null ;
	private String _sSqlWhere   = null ;
	private String _sSqlFrom    = null ;
	private String _sSqlSelect  = null ;
    
	public SqlQuerySplitter( String fullSqlSelectRequest ) 
	{
		if ( fullSqlSelectRequest != null )
		{
			String s = fullSqlSelectRequest ;
			s = processOrderByAndGroupBy(s) ;
			s = processWhere(s) ;
			s = processFrom(s) ;
			_sSqlSelect = s ; // The remaining part
		}
	}
	
	public String getSqlSelect() 
    {
		return _sSqlSelect ;
    }
	public String getSqlFrom() 
    {
		return _sSqlFrom ;
    }
	public String getSqlWhere() 
    {
		return _sSqlWhere ;
    }
	public String getSqlOrderByGroupBy() 
    {
		return _sSqlOrderByGroupBy ;
    }
    
    public String processFrom(String sqlSelectRequest) 
    {
    	String[] parts = null ;
        
        String s = sqlSelectRequest.toUpperCase();
        int i = s.indexOf(FROM) ;
    	if ( i >= 0 ) 
    	{
    		// Found
            parts = split(sqlSelectRequest, FROM );
            _sSqlFrom = parts[1]; // Can be null
            return parts[0]; // Return the left part
    	}
    	else 
    	{
    		_sSqlFrom = null ;
    		return sqlSelectRequest ;
    	}
    }
    
    public String processWhere(String sqlSelectRequest) 
    {
    	String[] parts = null ;
        
        String s = sqlSelectRequest.toUpperCase();
        int i = s.indexOf(WHERE) ;
    	if ( i >= 0 ) 
    	{
    		// Found
            parts = split(sqlSelectRequest, WHERE );
            _sSqlWhere = parts[1]; // Can be null
            return parts[0]; // Return the left part
    	}
    	else 
    	{
    		_sSqlWhere = null ;
    		return sqlSelectRequest ;
    	}
    }
    
    public String processOrderByAndGroupBy(String sqlSelectRequest) 
    {
    	String[] parts = null ;
        
        String s = sqlSelectRequest.toUpperCase();
        int iOrderBy = s.indexOf(ORDER) ;
        int iGroupBy = s.indexOf(GROUP) ;
        if ( iOrderBy >= 0 && iGroupBy >= 0 )  // GROUP BY and ORDER BY (both)
        {
            //--- Cut before the first one 
        	if ( iOrderBy < iGroupBy ) {
                parts = split(sqlSelectRequest, ORDER );
        	}
        	else {
                parts = split(sqlSelectRequest, GROUP );
        	}
        }
        else 
        {
        	if ( iOrderBy >= 0 ) 
        	{
        		// Only "ORDER BY"
                parts = split(sqlSelectRequest, ORDER );
        	}
        	else if ( iGroupBy >= 0 ) 
        	{
        		// Only "GROUP BY"
                parts = split(sqlSelectRequest, GROUP );
        	}
        	else 
        	{
        		// None 
                parts = new String[2] ;
            	parts[0] = sqlSelectRequest ;
            	parts[1] = null ;
        	}
        }
        _sSqlOrderByGroupBy = parts[1]; // Can be null
        return parts[0]; // Return the left part
    }
    
    public String[] split(String s, String mark) 
    {
        String leftPart = StrUtil.cutBeforeIgnoreCase(s, mark);
        String rightPart = null;
        if ( leftPart.length() < s.length() ) 
        {
        	// Different strings => 2 parts
        	rightPart = s.substring( leftPart.length(), s.length() ) ;
        }
        else 
        {
        	// Same size => same String => No right part 
        	rightPart = null;
        }

        String[] parts = new String[2] ;
    	parts[0] = leftPart ;
    	parts[1] = rightPart ;
    	return parts ;
    }
}
